#include "Edge.h"

Edge::Edge() {
    index = -1;
    sharpness = 0;
    startVertex = 0;
    endVertex = 0;
    ccVertex = 0;
    startEdge = 0;
    endEdge = 0;
    opt = false;
}

Edge::Edge(int index, Vertex* a, Vertex* b, int sharpness, bool opt) {
    this->index = index;
    startVertex = a;
    endVertex = b;

    this->sharpness = sharpness;
    this->opt = opt;

    ccVertex = 0;
    startEdge = 0;
    endEdge = 0;
}

Vector3d Edge::midpoint() const {
    return 0.5 * (startVertex->pos + endVertex->pos);
}

void Edge::setCC(Vertex* v, Edge* a, Edge* b) {
    Vector3d pos;
    if (sharpness) {
        pos = 0.5 * (startVertex->pos + endVertex->pos);
    } else {
        pos = 0.25 * (startVertex->pos + endVertex->pos + forwardFace->centroid() + reverseFace->centroid());
    }
    ccVertex = v;
    ccVertex->pos = pos;
    ccVertex->sharpness = 0;
    ccVertex->opt = opt || (startVertex->opt && endVertex->opt);

    startEdge = a;
    startEdge->startVertex = startVertex->ccVertex;
    startEdge->endVertex = v;
    startVertex->ccVertex->addEdge(a);
    v->addEdge(a);

    endEdge = b;
    endEdge->startVertex = endVertex->ccVertex;
    endEdge->endVertex = v;
    endVertex->ccVertex->addEdge(b);
    v->addEdge(b);
    
    if (sharpness > 0) {
        startEdge->sharpness = sharpness - 1;
        endEdge->sharpness = sharpness - 1;
    } else {
        startEdge->sharpness = sharpness;
        endEdge->sharpness = sharpness;
    }
}

bool Edge::equalEndpoints(int a, int b) const {
    return (startVertex->index == a && endVertex->index == b) || (startVertex->index == b && endVertex->index == a);
}

Vertex* Edge::getOpposite(const Vertex* v) const {
    if (v == startVertex) return endVertex;
    if (v == endVertex) return startVertex;
    return 0;
}

Face* Edge::getRightFace(const Vertex* v) const {
    if (v == startVertex) return reverseFace;
    if (v == endVertex) return forwardFace;
    return 0;
}
